const { Op } = require("sequelize");
const article = require('../model/article');
const Lables = require('../model/lables');
const articleAndLable = require('../model/articleAndLable');
const Pso = require('../model/posAndarticle');
let sequelize = require('../model/db.js')
const moment = require('moment')
class Article {
  /* 获取文章 */
  async getArticlename(name) {
    const onearticle = await article.findOne({ where: { article_title: name } });
    if (onearticle === null) {
      return {
        code: 1,
        msg: '文章不存在'
      }
    } else {
      return {
        code: 0,
        msg: '文章存在',
      }
    }
  }
  /* 创建文章 */
  async createArticle(articleinfo) {
    let res;
    try {
      // 判断当前分类是否存在，若是存在，则会有分类id
      res = await article.create(articleinfo);
    } catch (err) {
      console.log(err);
    }
    return res ? {
      code: 1,
      dataValues: res.dataValues,
      msg: '创建成功'
    } : {
      code: 0,
      dataValues: null,
      msg: '创建失败',
    }
  }
  /* 绑定文章与标签 */
  async bandArticleAndLable(article_id, lables) {
    try {
      /* 先根据名字查询标签 */
      let alllist = lables.map(async item => {
        const onelable = await Lables.findOne({ where: { lable_name: item } });
        if (onelable === null) {
          /* 如果等于null 就创建标签 */
          let newlable = await Lables.create({ lable_name: item });
          return {
            lable_id: newlable.id,
            lable_name: newlable.lable_name
          }
        } else {
          /* 找到了 */
          return {
            lable_id: onelable.id,
            lable_name: onelable.lable_name
          }
        }
      })
      let xx
      await Promise.all(alllist).then(res => {
        xx = res.map(i => {
          let article_lable = {
            article_id,
            lable_id: i.lable_id
          }
          return article_lable
        })
      })
      // 批量新增文章标签关联
      let resultList = await articleAndLable.bulkCreate(xx)
      return {
        data: resultList,
        code: 1,
        msg: '绑定成功'
      };
    } catch (error) {
      console.log(error);
    }

  }
  /* 普通分页获取文章列表 */
  getarticlelist = async (page, pageSize) => {
    if (page == null || pageSize == null) {
      return {
        code: 0,
        msg: '参数错误'
      }
    }
    page = (typeof page == "string") ? parseInt(page) : page;
    pageSize = (typeof pageSize == "string") ? parseInt(pageSize) : pageSize;
    let c = await article.count({
      where: {
        article_status: 1,
      },
    });
    const { count, rows } = await article.findAndCountAll({
      where: {
        article_status: 1
      },
      order: [["createdAt", "DESC"]],
      offset: (page - 1) * pageSize,
      limit: pageSize
    })

    if (rows.length == 0) {
      return {
        code: 0,
        msg: '暂无数据'
      }
    }
    let data = await this.returnarticle(rows)
    if (data.length > 0) {
      return {
        code: 1,
        msg: '获取成功',
        data,
        count: c,
      }
    }
  }
  /* 将文章与足迹组合返回 */
  getposandlist = async (page, pageSize) => {
    if (page == null || pageSize == null) {
      return {
        code: 0,
        msg: '参数错误'
      }
    }
    page = (typeof page == "string") ? parseInt(page) : page;
    pageSize = (typeof pageSize == "string") ? parseInt(pageSize) : pageSize;
    const { count, rows } = await article.findAndCountAll({
      where: {
        article_status: 1
      },
      offset: (page - 1) * pageSize,
      limit: pageSize
    })
    let c = await article.count({
      where: {
        article_status: 1,
      },
    });
    if (rows.length == 0) {
      return {
        code: 0,
        msg: '暂无数据'
      }
    }
    let data = await this.returnarticle(rows)
    let isok = data.map(async item => {
      let ress = await Pso.findOne({
        where: {
          articleid: item.id
        }
      })
      return ress ? {
        ...item,
        pos: ress.dataValues.pos_name
      } : {
        ...item,
        pos: ""
      }
    })
    let res = await Promise.all(isok)
    if (data.length > 0) {
      return {
        code: 1,
        msg: '获取成功',
        data: res,
        count: c,
      }
    }
  }
  /* 获取回收站文章的列表 */
  getrecyclelist = async (page, pageSize) => {
    if (page == null || pageSize == null) {
      return {
        code: 0,
        msg: '参数错误'
      }
    }
    page = (typeof page == "string") ? parseInt(page) : page;
    pageSize = (typeof pageSize == "string") ? parseInt(pageSize) : pageSize;
    const { count, rows } = await article.findAndCountAll({
      where: {
        article_status: 2
      },
      offset: (page - 1) * pageSize,
      limit: pageSize
    });
    let c = await article.count({
      where: {
        article_status: 2,
      },
    });
    let data = await this.returnarticle(rows)
    if (data.length > 0) {
      return {
        code: 1,
        msg: '获取成功',
        data,
        count: c,
      }
    } else {
      return {
        code: 0,
        msg: '无数据',
        count: c,
      }
    }
  }
  /* 根据找到每个文章对应的标签 返回组装好的标签文章列表 */
  async returnarticle(rows) {
    let articlelist = rows.map(async (item) => {
      let article = item.dataValues
      let article_lable = await articleAndLable.findAll({
        where: { article_id: article.id }
      })
      let article_lable_list = article_lable.map(async i => {
        let article_lable = i.dataValues
        let onelable = await Lables.findOne({
          where: { id: article_lable.lable_id }
        })
        let lablename = onelable?.dataValues.lable_name
        return lablename
      })
      let ress = await Promise.all(article_lable_list)
      return {
        ...article,
        lables: ress
      }
    })
    let data = await Promise.all(articlelist)
    return data
  }
  /* 查看置顶文章的个数 */
  async getAllowTotop() {
    let num = await article.count({
      where: {
        article_istop: true
      }
    })
    return num
  }
  /* 文章置顶 */
  async toTop(article_id) {
    let data = await article.update({ article_istop: true }, {
      where: {
        id: article_id
      }
    })
    console.log(data);
    if (data[0] > 0) {
      return {
        code: 1,
        msg: '置顶成功'
      }
    } else {
      return {
        code: 0,
        msg: '置顶失败'
      }
    }
  }
  /* 取消置顶 */
  async cancelTop(article_id) {
    let data = await article.update({ article_istop: false }, {
      where: {
        id: article_id
      }
    })
    console.log(data);
    if (data[0] > 0) {
      return {
        code: 1,
        msg: '取消置顶成功'
      }
    } else {
      return {
        code: 0,
        msg: '取消置顶失败'
      }
    }
  }
  /* 查看文章是否置顶 */
  async getistotop(article_id) {
    const project = await article.findOne({
      attributes: ["article_istop"],
      where: { id: article_id },
    })
    if (project == null) {
      return {
        code: 0,
        msg: '该文章不存在'
      }
    } else if (project.dataValues.article_istop == true) {
      return {
        code: 0,
        msg: '该文章已置顶'
      }
    } else {
      return {
        code: 1,
        msg: '该文章未置顶'
      }
    }
  }
  /* 通过文章id获取文章 */
  getArticleByid = async (article_id) => {
    let res = await article.findByPk(article_id)
    if (res) {
      let dataa = await this.returnarticle([res])
      if (dataa.length > 0) {
        return {
          code: 1,
          msg: '获取成功',
          data: dataa[0],
        }
      } else {
        return {
          code: 0,
          msg: '获取失败',
        }
      }
    }
  }
  /* 编辑文章 */
  async editArticle(article_id, data) {
    /* 查看分类变没有 */
    let { lables } = data
    /* 过滤对比两个标签不一样的，修改 */
    let res = await articleAndLable.findAll({
      attributes: ["lable_id"],
      where: { article_id },
    })
    /* 查询原来的文章标签的id列表 */
    let oldlable_id = res.map(item => {
      return item.dataValues.lable_id
    })
    /* 获取修改后的文章id列表 */
    let newlable_id = lables.map(async item => {
      let onelable = await Lables.findOne({ where: { lable_name: item } });
      if (onelable) {
        return onelable.dataValues.id
      }
    })
    let newlable_id_arr = await Promise.all(newlable_id)
    /* 利用set来查看双方的互不相同的元素 */
    let oldlable_map = new Set(oldlable_id)
    newlable_id_arr.forEach(async el => {
      if (oldlable_map.has(el)) {
      } else {
        let ress = await articleAndLable.create({
          lable_id: el,
          article_id
        })
      }
    })
    let newlable_map = new Set(newlable_id_arr)
    oldlable_id.forEach(async el => {
      if (newlable_map.has(el)) {

      } else {
        let ress = await articleAndLable.destroy({ where: { lable_id: el, article_id } })
      }
    })
    let dd = await article.update(data, { where: { id: article_id } });
    return dd[0] > 0 ? {
      code: 1,
      msg: "修改成功"
    } : {
      code: 0,
      msg: "修改失败"
    }
  }
  /* 修改文章的封面 */
  async editArticlecorver(article_id, article_cover) {
    let res = await article.update({ article_cover }, { where: { id: article_id } });
    return res[0] > 0 ? {
      code: 1,
      msg: "修改成功"
    } : {
      code: 0,
      msg: "修改失败"
    }
  }
  /* 删除文章 */
  async deleteArticleById(article_id) {
    let res = await article.destroy({ where: { id: article_id } });
    let ress = await Pso.destroy({ where: { articleid: article_id } })
    return res > 0 ? {
      code: 1,
      msg: "删除成功"
    } : {
      code: 0,
      msg: "删除失败"
    }
  }
  /* 删除文章对应的标签 */
  async deleteArticleTag(article_id) {
    let res = await articleAndLable.destroy({ where: { article_id } })
    console.log(res);
    return res > 0 ? {
      code: 1,
      msg: "删除成功"
    } : {
      code: 0,
      msg: "删除失败"
    }
  }
  /* 搜索文章 */
  async searcharticle(keyword) {
    let { article_title, article_istop, article_status, lable_id, page, pageSize, time } = keyword;
    console.log(article_title, article_istop, article_status, lable_id, page, pageSize, time);
    let whereobj = {}
    let pageinfo = {}
    if (lable_id) {
      lable_id = (typeof lable_id == "string") ? parseInt(lable_id) : lable_id
      let res = await articleAndLable.findAll({ attributes: ["article_id"], where: { lable_id } })
      let article_list = res.map(item => item.dataValues.article_id)
      Object.assign(whereobj, {
        id: {
          [Op.in]: article_list
        }
      })
    }
    page = (typeof page == "string") ? parseInt(page) : page;
    pageSize = (typeof pageSize == "string") ? parseInt(pageSize) : pageSize;
    if (time.length > 0) {
      time = time.map(item => {
        return moment(item).format("YYYY-MM-DD HH:mm:ss")
      })
      Object.assign(whereobj, {
        createdAt: {
          [Op.between]: time,
        },
      })
    }
    article_title && Object.assign(whereobj, {
      article_title: {
        [Op.like]: `%${article_title}%`,
      },
    })
    if (article_istop !== "") {
      Object.assign(whereobj, { article_istop })
    }
    article_status && Object.assign(whereobj, { article_status })
    const { count, rows } = await article.findAndCountAll({
      offset: (page - 1) * pageSize,
      limit: pageSize,
      where: whereobj,
      attributes: { exclude: ["article_content"] },
      order: [["createdAt", "DESC"]],
    });
    let ress = rows.map(item => item.dataValues)
    console.log(ress);
    if (rows.length > 0) {
      return {
        code: 1,
        msg: "获取成功",
        data: {
          count,
          articlelist: ress
        }
      }
    } else {
      return {
        code: 0,
        msg: "暂无数据",
        data: {}
      }
    }
  }
  /* 添加足迹 */
  async addposition(pos, article_id) {
    let res = await Pso.create({ pos_name: pos, articleid: article_id })
    if (res) {
      return {
        code: 1,
        msg: "添加成功"
      }
    } else {
      return {
        code: 0,
        msg: "添加失败"
      }
    }
  }
  /* 检查一篇文章足迹 */
  async getposition(article_id) {
    let res = await Pso.findAll({ where: { articleid: article_id } })
    if (res.length > 0) {
      return {
        code: 0,
        msg: "获取成功"
      }
    } else {
      return {
        code: 1,
        msg: "暂无数据"
      }
    }

  }
  getPreAndnextarticle = async (article_id) => {
    let left = await article.findOne({
      where: {
        id: {
          [Op.lt]: article_id
        },
        article_status: 1,
      },
      order: [["id", "DESC"]],
    })
    let right = await article.findOne({
      where: {
        id: {
          [Op.gt]: article_id
        },
        article_status: 1,
      },
      order: [["id", "DESC"]],
    })
    if (!left) {
      left = await article.findOne({
        where: {
          id: article_id
        }
      })
    }
    if (!right) {
      right = await article.findOne({
        where: {
          id: article_id
        }
      })
    }
    let dataa = await this.returnarticle([left, right])
    return {
      code: 1,
      msg: "获取成功",
      data: dataa
    }
  }
  async addview(id) {
    let res = await article.increment("article_viewtime", {
      where: {
        id,
      }
    })
    return {
      code: 1,
      msg: "更新成功",
      data: res
    }
  }
  async getrecommentarticle() {
    let res = await article.findAll({
      limit: 2,
      where: {
        article_status: 1,
        article_istop: true
      }
    })
    res = res.map(item => item.dataValues)
    let len = res.length
    if (len == 2) {
      return {
        code: 1,
        msg: "获取成功",
        data: res
      }
    } else {
      let limit = 2 - len
      let res1 = await article.findAll({
        limit,
        where: {
          article_status: 1,
          order: sequelize.literal('rand()')
        }
      })
      res1 = res1.map(item => item.dataValues)
      res = [...res, ...res1]
      return {
        code: 1,
        msg: "获取成功",
        data: res
      }
    }
  }
  async getarticlenums() {
    let res = await article.count({
      where: {
        article_status: 1
      }
    })
    return {
      code: 1,
      msg: "获取成功",
      data: res
    }
  }
  async getpos() {
    let res = await Pso.findAll({
      attributes: ["pos_name", "articleid"],
    })
    let addresslist = res.map(item => item.dataValues.pos_name)
    let articleid = res.map(item => item.dataValues.articleid)
    if (articleid.length == 0) {
      return {
        code: 0,
        msg: "暂无数据",
        data: {}
      }
    } else {
      let ress = await article.findAll({
        where: {
          article_status: 1,
          id: {
            [Op.in]: articleid
          }
        }
      })
      let i = 0
      ress = ress.map(item => {
        return {
          ...item.dataValues,
          pos_name: addresslist[i++]
        }
      })
      console.log(ress);
      return {
        code: 1,
        msg: "获取成功",
        data: ress
      }
    }

  }
  async setlike(id, status) {
    let res
    if (status == 1) {
      res = await article.increment("articlee_strs", {
        where: {
          id,
        }
      })
    } else {
      res = await article.decrement("articlee_strs", {
        where: {
          id,
        }
      })
    }
    return {
      code: 1,
      msg: "点赞成功",
      data: res
    }
  }
  async searchinfo(content) {
    let res = await article.findAll({
      where: {
        article_content: {
          [Op.like]: `%${content}%`,
        },
        article_status: 1,
      },
      attributes: ["id", "article_title", "article_content","article_description"],
      limit: 8,
      order: [["article_viewtime","DESC"]],
    })
    let result = []
     res &&
     res.forEach((r) => {
      let { id, article_content, article_title ,article_description} = r.dataValues;
      let index = article_content.search(content)+content.length;
      let previous = index;
      let next = index+10;
      result.push({
        id,
        article_content: article_content.substring(previous, next),
        article_title,
        article_description,
        keyword:content
      });
    });
    return {
      code: 1,
      data:result
    }
  }
}
module.exports = new Article();
